package com.summer.oauth.center.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.summer.user.center.api.UserService;
import com.summer.util.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;

import javax.servlet.http.HttpServletRequest;
import java.util.HashSet;
import java.util.Set;

/**
 * 查询数据库鉴定是否有权限
 */
@Component("rbacService")
public class RbacServiceImpl implements RbacService {

    private AntPathMatcher antPathMatcher = new AntPathMatcher();

    @Autowired
    private UserService userService;

    @Autowired
    private RedisUtil redisUtil;

    public final static String RESOURCE_CACHE_PREFIX = "summer:resource:";

    @Override
    public boolean hasPermission(HttpServletRequest request, Authentication authentication) {
        Object principal = authentication.getPrincipal();
        if (principal instanceof UserDetails) {
            String username = ((UserDetails) principal).getUsername();
            if (StrUtil.isEmpty(username)) {
                return false;
            }

            HashSet<String> resource = null;
            //先获取缓存的权限数据
            String key = RESOURCE_CACHE_PREFIX + username;
            if (redisUtil.exists(key)) {
                resource = redisUtil.getHashSet(key, String.class);
            } else {
                //缓存中无数据,从数据库中查询数据
                resource = userService.findResourceByUsername(username);
                if (CollUtil.isNotEmpty(resource)) {
                    redisUtil.set(key, resource);
                }
            }

            if (CollUtil.isNotEmpty(resource)) {
                String requestURI = request.getRequestURI();
                if (resource.contains(requestURI)) {
                    return true;
                }

                for (String url : resource) {
                    if (antPathMatcher.match(url, requestURI)) {
                        return true;
                    }
                }
            }
        }
        return false;
    }
}
